#include "synapse.h"
#include <stdexcept>

synapse::synapse(){
    f_signal = 0.;
    b_signal = 0.;
    weight   = 1;
    for(int icount = 0; icount < MAX_STUDY_SIGNAL_BUFFER; icount ++)
    {
        f_signal_study[icount] = 0.0;
        b_signal_study[icount] = 0.0;
        weight_back[icount]    = 0.0;
    }
}

synapse::synapse(const ntype::signal_t &fs, const ntype::signal_t &bs, const ntype::weight_t &w){
    f_signal = fs;
    b_signal = bs;
    weight   = w;
    for(int icount = 0; icount < MAX_STUDY_SIGNAL_BUFFER; icount ++)
    {
        f_signal_study[icount] = 0.0;
        b_signal_study[icount] = 0.0;
        weight_back[icount]    = 0.0;
    }
}

synapse::synapse(const synapse &s){
    f_signal = s.f_signal;
    b_signal = s.b_signal;
    weight   = s.weight;

    for(int icount = 0; icount < MAX_STUDY_SIGNAL_BUFFER; icount ++)
    {
        f_signal_study[icount] = s.f_signal_study[icount];
        b_signal_study[icount] = s.b_signal_study[icount];
        weight_back[icount]    = s.weight_back[icount];
    }
}

synapse::~synapse(void){
}

ntype::signalid_t synapse::getMaxSignalStudyBufferIndex() const
{
    return MAX_STUDY_SIGNAL_BUFFER;
}

void synapse::setFSignal(ntype::signal_t s){
    f_signal = s;
}

ntype::signal_t synapse::getFSignal(void){
    return f_signal;
}

void synapse::setBSignal(ntype::signal_t s){
    b_signal = s;
}

ntype::signal_t synapse::getBSignal(void){
    return b_signal;
}
void synapse::setWeight(ntype::weight_t v) {
    weight = v;
}

ntype::weight_t synapse::getWeight() {
    return weight;
}

void synapse::setFSignalStudy(ntype::signalid_t signalid, ntype::signal_t value)
{
    if(signalid >= MAX_STUDY_SIGNAL_BUFFER)
        throw std::overflow_error("synapse::setFSignalStudy: signal id more max value");
    f_signal_study[signalid] = value;
}

void synapse::setBSignalStudy(ntype::signalid_t signalid, ntype::signal_t value)
{
    if(signalid >= MAX_STUDY_SIGNAL_BUFFER)
        throw std::overflow_error("synapse::setBSignalStudy: signal id more max value");
    b_signal_study[signalid] = value;
}

void synapse::setWeightBack(ntype::signalid_t signalid, ntype::weight_t value)
{
    if(signalid >= MAX_STUDY_SIGNAL_BUFFER)
        throw std::overflow_error("synapse::setWeightBack: signal id more max value");
    weight_back[signalid] = value;
}

ntype::signal_t synapse::getFSignalStudy(ntype::signalid_t signalid)
{
    if(signalid >= MAX_STUDY_SIGNAL_BUFFER)
        throw std::overflow_error("synapse::getFSignalStudy: signal id more max value");
    return f_signal_study[signalid];
}

ntype::signal_t synapse::getBSignalStudy(ntype::signalid_t signalid)
{
    if(signalid >= MAX_STUDY_SIGNAL_BUFFER)
        throw std::overflow_error("synapse::getBSignalStudy: signal id more max value");
    return b_signal_study[signalid];
}

ntype::weight_t synapse::getWeightBack(ntype::signalid_t signalid)
{
    if(signalid >= MAX_STUDY_SIGNAL_BUFFER)
        throw std::overflow_error("synapse::getWeightBack: signal id more max value");
    return weight_back[signalid];
}

ntype::error_t synapse::getError(ntype::signalid_t signalid)
{
    ntype::signal_t diff = getFSignalStudy(signalid) - getBSignalStudy(signalid);
    ntype::signal_t max_v = std::max(getFSignalStudy(signalid), getBSignalStudy(signalid));
    return (diff / max_v);
}
